using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;

using Kiiro.Common;
using Kiiro.Common.Entities;
using Kiiro.Model;
using Kiiro.Common.Utility;

using Security = Kiiro.Common.Utility.Constants.Security;

namespace Kiiro.KeyGenerator
{
    public partial class KeyGenerator : Form
    {
        string message = string.Empty;

        public KeyGenerator ( )
        {
            InitializeComponent ( );

            this.dtpExpiryDate.Value = DateTime.Today.AddYears ( 1 );
        }

        private bool IsValid ( )
        {
            bool isValid = true;
            int result = default ( int );

            Encoding Encoder = ASCIIEncoding.Default;
            Byte [ ] buffer = new byte [ ] { ( byte ) 149 };
            string bullet = Encoding.GetEncoding ( 1252 ).GetString ( buffer );

            if ( !rbServer.Checked && !rbInstance.Checked )
            {
                isValid = false;
                message += bullet + " License Type is required." + Environment.NewLine;
            }
            else if ( rbServer.Checked && rbInstance.Checked )
            {
                isValid = false;
                message += bullet + " Only one license type can be selected." + Environment.NewLine;
            }

            if ( !this.cboActiveProjectsLimitNo.Checked )
            {
                if ( string.IsNullOrEmpty ( this.txtActiveProjectsLimit.Text.Trim ( ) ) )
                {
                    isValid = false;
                    message += bullet + " Active Projects is required." + Environment.NewLine;
                }
                else
                {
                    if ( !Int32.TryParse ( this.txtActiveProjectsLimit.Text.Trim ( ), out result ) )
                    {
                        isValid = false;
                        message += bullet + " Active Projects must be an integer greater than or equal to 0." + Environment.NewLine;
                    }
                }
            }

            if ( !this.cboActiveUsersLimitNo.Checked )
            {
                if ( string.IsNullOrEmpty ( this.txtActiveUsersLimit.Text.Trim ( ) ) )
                {
                    isValid = false;
                    message += bullet + " Active Users is required." + Environment.NewLine;
                }
                else
                {
                    if ( !Int32.TryParse ( this.txtActiveUsersLimit.Text.Trim ( ), out result ) )
                    {
                        isValid = false;
                        message += bullet + " Active Users must be an integer greater than or equal to 0." + Environment.NewLine;
                    }
                }
            }

            return isValid;
        }

        protected void btnGenerateEncryptedKey_Click ( object sender, EventArgs e )
        {
            bool valid = this.IsValid ( );

            if ( valid )
            {
                LicensingManifest manifest = new LicensingManifest ( );

                if ( !this.cboActiveProjectsLimitNo.Checked )
                    manifest.OpenProjectsLimit = Double.Parse ( this.txtActiveProjectsLimit.Text.Trim ( ) );
                else
                    manifest.OpenProjectsLimit = Double.PositiveInfinity;

                if ( !this.cboActiveUsersLimitNo.Checked )
                    manifest.ActiveUsersLimit = Double.Parse ( this.txtActiveUsersLimit.Text.Trim ( ) );
                else
                    manifest.ActiveUsersLimit = Double.PositiveInfinity;

                if ( !this.cboExpiryDateNo.Checked )
                    manifest.ExpiryDate = this.dtpExpiryDate.Value;
                else
                    manifest.ExpiryDate = DateTime.MaxValue;

                manifest.InstallCode = txtInstallCode.Text.Trim ( );

                manifest.IsServerLicense = rbServer.Checked;

                //encrypt the string:
                string encryptedLicenseKey = KiiroEncryption.Instance.TripleDESEncrypt ( manifest.GetManifestCSV ( ) );

                txtEncryptedKey.Text = encryptedLicenseKey;

                SaveFileDialog saveFileDialog = new SaveFileDialog ( );
                saveFileDialog.RestoreDirectory = true;
                saveFileDialog.Filter = "lic files(*.lic)|*.lic";
                saveFileDialog.DefaultExt = "lic";
                saveFileDialog.FileName = "kiiro.lic";

                if ( saveFileDialog.ShowDialog ( ) == DialogResult.OK )
                {
                    Stream streamToWrite;
                    if ( ( streamToWrite = saveFileDialog.OpenFile ( ) ) != null )
                    {
                        StreamWriter writer = new StreamWriter ( streamToWrite );

                        try
                        {
                            writer.Write ( encryptedLicenseKey );
                            writer.Close ( );
                            message = "License Key saved successfully";
                            MessageBox.Show ( message, "Success" );

                            this.txtActiveProjectsLimit.Text = string.Empty;
                            this.cboActiveProjectsLimitNo.Checked = false;
                            this.txtActiveUsersLimit.Text = string.Empty;
                            this.cboActiveUsersLimitNo.Checked = false;
                            this.dtpExpiryDate.Value = DateTime.Today.AddYears ( 1 );
                            this.cboExpiryDateNo.Checked = false;
                        }
                        catch
                        {
                            message = "An error occured when saving the License Key.";
                            MessageBox.Show ( message, "Error" );
                        }
                        finally
                        {
                            writer.Close ( );
                            writer.Dispose ( );
                        }
                    }
                }
            }
            else
            {
                MessageBox.Show ( message, "Error" );
            }

            message = string.Empty;
        }

        protected void btnBrowse_Click ( object sender, EventArgs e )
        {
            OpenFileDialog openFileDialog = new OpenFileDialog ( );
            openFileDialog.RestoreDirectory = true;
            openFileDialog.Filter = "lic files(*.lic)|*.lic";
            openFileDialog.DefaultExt = "lic";

            if ( openFileDialog.ShowDialog ( ) == DialogResult.OK )
            {
                if ( openFileDialog.FileName.Trim ( ).Length > 0 )
                {
                    this.txtFileToDecrypt.Text = openFileDialog.FileName.Trim ( );
                }
            }
        }

        protected void btnDecrypt_Click ( object sender, EventArgs e )
        {
            bool valid = true;
            bool validKey = true;

            this.txtDecryptedOutput.Clear ( );

            if ( string.IsNullOrEmpty ( this.txtFileToDecrypt.Text.Trim ( ) ) )
            {
                message = "File to Decrypt is required.";
                valid = false;
            }
            else if ( !this.txtFileToDecrypt.Text.Trim ( ).EndsWith ( ".lic" ) )
            {
                message = "File to Decrypt must be of type '*.lic'.";
                valid = false;
            }
            else
            {
                StreamReader reader = new StreamReader ( this.txtFileToDecrypt.Text.Trim ( ) );
                string [ ] elements = LicensingManifest.GetLicensingManifest ( reader.ReadLine ( ) ).GetManifestCSV ( ).Split ( ',' );

                foreach ( string element in elements )
                {
                    this.txtDecryptedOutput.Text += element.Replace ( '|', ':' ) + Environment.NewLine;
                }

                reader.Close ( );
                reader.Dispose ( );
            }

            if ( !valid )
            {
                MessageBox.Show ( message, "Error" );
            }

            message = string.Empty;
        }

        private void rbInstance_CheckedChanged ( object sender, EventArgs e )
        {
            rbServer.Checked = !rbInstance.Checked;
        }

        private void rbServer_CheckedChanged ( object sender, EventArgs e )
        {
            rbInstance.Checked = !rbServer.Checked;
        }
    }
}